<script setup lang="ts">
import type { FormInstance } from 'ant-design-vue';

import type { PropType } from 'vue';

import { computed, nextTick, reactive, ref, watch } from 'vue';

import { Modal } from 'ant-design-vue';

import { paymentAdjustmentApply } from '#/api/hm/paymentAdjustment';

// 定义订单数据接口
interface OrderDataType {
  saleId: number | string;
  customerName: string;
  saleAmount: number;
  returnAmount: number;
  refundSurplusNum: number; // 未回款金额
}

// 定义组件的 props
const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  orderData: {
    type: Object as PropType<null | OrderDataType>,
    default: null,
  },
});

// 定义组件的 emits
const emit = defineEmits(['update:visible', 'success']);

const modalVisible = ref(false);
const loading = ref(false);
const formRef = ref<FormInstance>();
const errorMessage = ref('');
const fileList = ref<any[]>([]);

// 表单初始状态
const initialFormState = () => ({
  adjustmentType: undefined as string | undefined,
  adjustmentAmount: null as null | number,
  description: '',
  proofFileList: [] as string[],
});

const formState = reactive(initialFormState());

// 计算调整后的未回款金额
const newUnpaidAmount = computed(() => {
  if (!props.orderData) return 0;
  const originalUnpaid = props.orderData.refundSurplusNum || 0;
  const adjustAmount = formState.adjustmentAmount || 0;
  return originalUnpaid - adjustAmount;
});

// 监听弹窗显示状态
watch(
  () => props.visible,
  async (val) => {
    modalVisible.value = val;
    if (val) {
      Object.assign(formState, initialFormState());
      fileList.value = [];
      errorMessage.value = '';
      await nextTick();
      formRef.value?.clearValidate();
    }
  },
);

// 表单校验规则
const validateAdjustmentAmount = (_rule: any, value: null | number) => {
  if (value === null || value === undefined) {
    return Promise.reject('请输入调整金额');
  }
  if (value < 0) {
    return Promise.reject('调整金额不能为负数');
  }
  const newAmount = (props.orderData?.refundSurplusNum || 0) - value;
  if (newAmount < 0) {
    return Promise.reject('调整后的未回款金额不能为负数');
  }
  return Promise.resolve();
};

const handleCancel = () => {
  modalVisible.value = false;
  emit('update:visible', false);
};

// 文件上传成功处理
const handleUploadSuccess = (response: any) => {
  if (response?.data?.url) {
    formState.proofFileList.push(response.data.url);
  }
};

// 文件删除处理
const handleFileRemove = (file: any) => {
  const url = file.response?.data?.url || file.url;
  const index = formState.proofFileList.indexOf(url);
  if (index !== -1) {
    formState.proofFileList.splice(index, 1);
  }
};

// 提交申请
const handleOk = async () => {
  errorMessage.value = '';
  if (!formRef.value) {
    errorMessage.value = '表单引用未就绪。';
    return;
  }

  try {
    // 表单校验
    await formRef.value.validate();

    // 二次确认
    Modal.confirm({
      title: '确认提交',
      content: '您确定要提交此回款调整申请吗？申请提交后将进入审核流程。',
      okText: '确认提交',
      cancelText: '我再想想',
      centered: true,
      onOk: async () => {
        try {
          loading.value = true;

          const payload: any = {
            saleId: props.orderData?.saleId,
            adjustmentType: formState.adjustmentType,
            adjustmentAmount: formState.adjustmentAmount,
            description: formState.description,
            proofFileList:
              formState.proofFileList.length > 0
                ? formState.proofFileList
                : undefined,
          };

          if (!payload.proofFileList) {
            delete payload.proofFileList;
          }

          await paymentAdjustmentApply(payload);
          emit('success');
          handleCancel();
        } catch (apiError: any) {
          errorMessage.value = `提交API请求失败: ${apiError?.message || '未知错误'}`;
          console.error('API提交失败详情:', apiError);
        } finally {
          loading.value = false;
        }
      },
      onCancel: () => {
        console.log('用户取消了提交申请。');
      },
    });
  } catch (formValidationError: any) {
    if (formValidationError?.errorFields) {
      console.warn('表单校验未通过:', formValidationError.errorFields);
    } else {
      errorMessage.value = `表单处理时发生错误: ${formValidationError?.message || '请检查表单内容'}`;
      console.error('表单校验或处理错误:', formValidationError);
    }
  }
};
</script>

<template>
  <a-modal
    v-model:open="modalVisible"
    title="申请回款调整"
    width="700px"
    :confirm-loading="loading"
    @ok="handleOk"
    @cancel="handleCancel"
    wrap-class-name="payment-adjustment-modal"
    :destroy-on-close="true"
  >
    <a-form
      :model="formState"
      ref="formRef"
      layout="vertical"
      v-if="modalVisible && orderData"
    >
      <a-alert
        v-if="errorMessage"
        :message="errorMessage"
        type="error"
        show-icon
        class="mb-4"
      />

      <a-divider>订单信息</a-divider>
      <a-descriptions bordered size="small" class="mb-4" :column="2">
        <a-descriptions-item label="订单号">
          {{ orderData.saleId }}
        </a-descriptions-item>
        <a-descriptions-item label="客户名称">
          {{ orderData.customerName }}
        </a-descriptions-item>
        <a-descriptions-item label="订单金额">
          ¥{{ orderData.saleAmount }}
        </a-descriptions-item>
        <a-descriptions-item label="已回款">
          ¥{{ orderData.returnAmount }}
        </a-descriptions-item>
        <a-descriptions-item label="未回款" :span="2">
          <a-tag color="warning"> ¥{{ orderData.refundSurplusNum }} </a-tag>
        </a-descriptions-item>
      </a-descriptions>

      <a-divider>调整信息</a-divider>

      <a-form-item
        label="调整类型"
        name="adjustmentType"
        :rules="[
          { required: true, message: '请选择调整类型', trigger: 'change' },
        ]"
      >
        <a-select
          v-model:value="formState.adjustmentType"
          placeholder="请选择调整类型"
          style="width: 100%"
        >
          <a-select-option value="DEBT_RELIEF">债务减免</a-select-option>
          <a-select-option value="ERROR_CORRECTION">错误修正</a-select-option>
          <a-select-option value="BAD_DEBT">坏账核销</a-select-option>
          <a-select-option value="AGING_ADJUSTMENT">账龄调整</a-select-option>
          <a-select-option value="DEBT_RESTRUCTURE">债务重组</a-select-option>
          <a-select-option value="OTHER">其他</a-select-option>
        </a-select>
      </a-form-item>

      <a-form-item
        label="调整金额（元）"
        name="adjustmentAmount"
        :rules="[{ validator: validateAdjustmentAmount, trigger: 'change' }]"
      >
        <a-input-number
          v-model:value="formState.adjustmentAmount"
          :precision="2"
          :min="0"
          :max="orderData.refundSurplusNum"
          style="width: 100%"
          placeholder="请输入调整金额"
        />
        <div class="mt-1 text-xs text-gray-500">
          提示：正数表示减少未回款，负数表示增加未回款
        </div>
      </a-form-item>

      <a-form-item label="调整后未回款">
        <a-tag :color="newUnpaidAmount >= 0 ? 'success' : 'error'">
          ¥{{ newUnpaidAmount.toFixed(2) }}
        </a-tag>
      </a-form-item>

      <a-form-item
        label="详细说明"
        name="description"
        :rules="[
          { required: true, message: '请输入详细说明', trigger: 'blur' },
          { max: 500, message: '详细说明不能超过500个字符', trigger: 'blur' },
        ]"
      >
        <a-textarea
          v-model:value="formState.description"
          :rows="4"
          :maxlength="500"
          show-count
          placeholder="请详细说明调整原因"
        />
      </a-form-item>

      <a-form-item label="证明材料">
        <a-upload
          v-model:file-list="fileList"
          action="/api/upload"
          list-type="picture-card"
          :before-upload="() => true"
          @success="handleUploadSuccess"
          @remove="handleFileRemove"
        >
          <div v-if="fileList.length < 8">
            <plus-outlined />
            <div class="mt-2">上传</div>
          </div>
        </a-upload>
        <div class="mt-1 text-xs text-gray-500">
          支持图片、PDF文件，单个文件不超过5MB
        </div>
      </a-form-item>
    </a-form>

    <template #footer>
      <a-button @click="handleCancel">取消</a-button>
      <a-button type="primary" :loading="loading" @click="handleOk">
        提交申请
      </a-button>
    </template>
  </a-modal>
</template>

<style scoped>
.mb-4 {
  margin-bottom: 1rem;
}

.mt-1 {
  margin-top: 0.25rem;
}

.mt-2 {
  margin-top: 0.5rem;
}

.text-xs {
  font-size: 0.75rem;
}

.text-gray-500 {
  color: #6b7280;
}

:deep(.payment-adjustment-modal .ant-modal-body) {
  max-height: calc(80vh - 120px);
  overflow-y: auto;
}
</style>
